package com.example.demo.config;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.dao.MessageDao;
import com.example.demo.dao.UserDao;
import com.example.demo.dao.UserDb;
import com.example.demo.entity.Message;
import com.example.demo.entity.User;
import com.example.demo.service.MessageImpl;
import com.example.demo.service.MessageService;
import com.example.demo.service.UserService;
import com.example.demo.service.UserServiceImpl;
import com.example.demo.uitls.GetHttpSessionConfigurator;
import com.example.demo.uitls.MessageUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Service
@ServerEndpoint(value = "/ws/chatroom/{roomId}", configurator = GetHttpSessionConfigurator.class)
public class Websocket extends HttpServlet {
    // 用Map集合存储所有客户端对应的ChatEndPoint对象

    private static MessageImpl messageService;
    private static UserServiceImpl userService;

    @Autowired
    public void setMessageService(MessageImpl messageService) {
        Websocket.messageService = messageService;
    }

    @Autowired
    public void setUserService(UserServiceImpl userService) {
        Websocket.userService = userService;
    }

    private static final Map<String, Websocket> onlineUsers = new ConcurrentHashMap<>();

    private Session session;

    private HttpSession httpSession;

    private Set<String> getIds() {
        return onlineUsers.keySet();
    }

    /**
     * 连接建立时被调用
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {

        // 将局部Session对象赋值给成员session
        this.session = session;
        System.out.println(session);
        onlineUsers.put(session.getId(), this);
    }

    // 广播消息
    private void broadcastAllUsers(String message) {
        // 获取所有在线用户的ChatEndPoint对象
        Set<String> userIds = getIds();
        for (String userId : userIds) {
            Websocket chatEndPoint = onlineUsers.get(userId);
            try {
                // 发送消息
                chatEndPoint.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 接收到客户端发送的数据时被调用
     */
    @OnMessage
    public void onMessage(String message, Session session) throws JsonProcessingException {
        try {
            // 解析客户端发送的消息
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode node = objectMapper.readTree(message);
            int room_id = node.get("roomId").asInt();
            int user_id = node.get("userId").asInt();
            String content = node.get("content").asText();

            // 将消息存入数据库
            Message message1 = new Message();
            message1.setRoomId(room_id);
            message1.setUserId(user_id);
            message1.setContent(content);
            messageService.add(message1);

            // 获取用户信息
            User user = userService.findByById(user_id);
            String username = user.getUsername();

            // 广播消息
            String broadcastMessage = MessageUtils.responseMessage(username, content);
            broadcastAllUsers(broadcastMessage);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 连接关闭时被调用
     */
    @OnClose
    public void onClose(Session session) {
        onlineUsers.remove(session.getId());
    }
}